package com.jmga.ecogasfinder.services;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

import org.w3c.dom.DOMException;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import android.app.Service;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.util.Log;

import com.google.android.maps.MapView;
import com.jmga.ecogasfinder.R;
import com.jmga.ecogasfinder.activities.Preferences;
import com.jmga.ecogasfinder.providers.GasFinderProvider;
import com.jmga.ecogasfinder.vo.GasStation;

public class StationUpdaterService extends Service {
	MapView myMapView = null;
	public static final String SHOW_TOP_TEN = "SHOW_TOP_TEN";
	
	@Override
	public void onCreate() {
		super.onCreate();
	}

	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.d(getClass().getName(), "onStartCommand: " + intent.getAction() + "Flags: " + flags + " startId " + startId);
		if ((flags & START_FLAG_RETRY) == 0) {
			// if it's a restart, do something.
		} else {
			// Alternative background process.
		}
		Context context = getApplicationContext();
		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
		
		int gasType = Integer.parseInt(prefs.getString(Preferences.PREF_GAS_TYPE, "1"));
		stationUpdate(gasType);

		return START_STICKY;
	}
	
	private void stationUpdate(int gasType) {
		GasStationUpdaterTask gasStationUpdater = new GasStationUpdaterTask();
		Object[] parameters = new Object[1];
		parameters[0] = Integer.valueOf(gasType);
		
		gasStationUpdater.execute(parameters);
	}
	
	private class GasStationUpdaterTask extends AsyncTask<Object, GasStation, Void> {
		@Override
		protected Void doInBackground(Object... params) {
			Cursor cursor;			
			URL url;
			int gasType = (Integer) params[0];
			GasStation gasStation = null;
			String whereFavouriteAndObservable = GasFinderProvider.KEY_FAVOURITE + " = 1 OR " + GasFinderProvider.KEY_OBSERVABLE + " = 1";
			cursor = getContentResolver().query(GasFinderProvider.CONTENT_URI_STATIONS, null, whereFavouriteAndObservable, null, null);

			if(cursor.getCount() != 0) {
				String xkeyString, labelString = null, operatorString = null, addressString = null, laneString = null, postalCodeString = null, provinceString = null,
	    			localityString = null, saleTypeString = null, sentTypeString = null, xCoordString = null, yCoordString = null;
		    	
				for(int i=0; cursor.moveToNext(); i++) {
					xkeyString = cursor.getString(cursor.getColumnIndexOrThrow(GasFinderProvider.KEY_XKEY));
					labelString = cursor.getString(cursor.getColumnIndexOrThrow(GasFinderProvider.KEY_LABEL));
			        operatorString = cursor.getString(cursor.getColumnIndexOrThrow(GasFinderProvider.KEY_OPERATOR));
			        addressString = cursor.getString(cursor.getColumnIndexOrThrow(GasFinderProvider.KEY_ADDRESS));
			        laneString = cursor.getString(cursor.getColumnIndexOrThrow(GasFinderProvider.KEY_LANE));
			        postalCodeString = cursor.getString(cursor.getColumnIndexOrThrow(GasFinderProvider.KEY_POSTAL_CODE));
			        provinceString = cursor.getString(cursor.getColumnIndexOrThrow(GasFinderProvider.KEY_PROVINCE));
			        localityString = cursor.getString(cursor.getColumnIndexOrThrow(GasFinderProvider.KEY_LOCALITY));
			        saleTypeString = cursor.getString(cursor.getColumnIndexOrThrow(GasFinderProvider.KEY_SALE_TYPE));
			        sentTypeString = cursor.getString(cursor.getColumnIndexOrThrow(GasFinderProvider.KEY_SENT_TYPE));
			        double xCoord = cursor.getDouble(cursor.getColumnIndexOrThrow(GasFinderProvider.KEY_X_COORD));
			        double yCoord = cursor.getDouble(cursor.getColumnIndexOrThrow(GasFinderProvider.KEY_Y_COORD));
			        xCoordString = String.valueOf(xCoord);
			        yCoordString = String.valueOf(yCoord);
			        
			        try {
						String gasStationsLookupFeed = getString(R.string.gas_station_feed);
						gasStationsLookupFeed += "&" + getString(R.string.gasTypeParam_feed) +  "=" + gasType;
						gasStationsLookupFeed += "&" + getString(R.string.BBOXParam_feed) +  "=" + xkeyString;
						
						url = new URL(gasStationsLookupFeed);
						
						Log.d(getClass().getName(), "START-Favourite-Station-Update:" + url.toExternalForm());
						
						URLConnection connection;
						connection = url.openConnection();

						HttpURLConnection httpConnection = (HttpURLConnection) connection;
						int responseCode = httpConnection.getResponseCode();

						if (responseCode == HttpURLConnection.HTTP_OK) {
							XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
							factory.setNamespaceAware(true);
					        XmlPullParser xpp = factory.newPullParser();
					        xpp.setInput(httpConnection.getInputStream(), "ISO-8859-1");
					        
					        int eventType = xpp.getEventType();
					        
					        String priceString = null, dateString = null, hourString = null;
					        
				        	while (eventType != XmlPullParser.END_DOCUMENT ){
				                String name = null;
				                switch (eventType){
				                	case XmlPullParser.START_TAG:
				                		name = xpp.getName();
				                		if (name.equalsIgnoreCase("Precio")){
				                			priceString = xpp.nextText();
				                		} else if (name.equalsIgnoreCase("Fecha")){
				                			dateString = xpp.nextText();
				                		} else if (name.equalsIgnoreCase("Hora")){
				                			hourString = xpp.nextText();
				                		}
				                		break;
				                	case XmlPullParser.END_TAG:
				                		name = xpp.getName();
				                		if (name.equalsIgnoreCase("estaciones_servicio_brief")){
				                			SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm", Locale.getDefault());
				    						Date fecha = new GregorianCalendar(0, 0, 0).getTime();
				    						float price = 0.0f;
				    						try {
				    							fecha = sdf.parse(dateString + " " + hourString);
				    							NumberFormat format = NumberFormat.getInstance(Locale.FRENCH);
				    							price = (format.parse(priceString)).floatValue();
				    						} catch (ParseException e) {
				    							e.printStackTrace();
				    						}
				    						
				    						gasStation = new GasStation(labelString, operatorString, addressString,
				    								laneString,	postalCodeString, provinceString, localityString, fecha,
				    								saleTypeString,	sentTypeString, xCoordString, yCoordString, xkeyString, price);
				    						
				    						addNewGS(gasStation, String.valueOf(gasType), priceString);
				    						publishProgress(gasStation);
				                		}
				                		break;
				                }
				                eventType = xpp.next();
					        }
						}
					} catch (MalformedURLException e) {
						e.printStackTrace();
					} catch (IOException e) {
						e.printStackTrace();
					} catch (DOMException e) {
						e.printStackTrace();
					} catch (XmlPullParserException e) {
						e.printStackTrace();
					} finally {}
				}
			}
			return null;
	    }
		
		private void addNewGS(GasStation gasStation, String fuelType, String precio) {
			ContentResolver cr = getContentResolver();
			
			String wherePrice = GasFinderProvider.KEY_DATE + " = " + gasStation.getDate().getTime();
			wherePrice += " AND " + GasFinderProvider.KEY_GAS_TYPE + " = '" + fuelType + "'";
			wherePrice += " AND " + GasFinderProvider.KEY_STATION + " = '" + gasStation.getXCoord() + gasStation.getYCoord() + "'";
			
			Cursor cursor = cr.query(GasFinderProvider.CONTENT_URI_PRICES, null,
					wherePrice, null, null);
			
			ContentValues values = null;
			
			Log.d(getClass().getName(), "Sql-insert-price " + wherePrice);
			if (cursor.getCount() == 0) {
				values = new ContentValues();

				values.put(GasFinderProvider.KEY_DATE, gasStation.getDate().getTime());
				values.put(GasFinderProvider.KEY_STATION, gasStation.getXCoord() + gasStation.getYCoord());
				values.put(GasFinderProvider.KEY_PRICE, precio);
				values.put(GasFinderProvider.KEY_GAS_TYPE, fuelType); // BUSCAR EN LA TABLA DE TIPO DE COMBUSTIBLE

				cr.insert(GasFinderProvider.CONTENT_URI_PRICES, values);
				Log.d(getClass().getName(), "addPrice-Data-Inserted:" + gasStation.getXkey() + ":" + precio + ":" + fuelType + ":" + gasStation.getDate().getTime());
			}
			cursor.close();
		}
		
		@Override
	    protected void onProgressUpdate(GasStation... values) {

	    }
	
	    @Override
	    protected void onPostExecute(Void result) {
			Intent intentLoading = new Intent(SHOW_TOP_TEN);
			Log.d(getClass().getName(), "sendBroadcast:" + SHOW_TOP_TEN);
			sendBroadcast(intentLoading);
	    	stopSelf();
	    }
	}
}
